
/*
 * Este programa calcula la inversa de una matriz cuadrada si es que existe.
 *
 * Para la inversión de la matriz especificada A, se realiza el siguiente proceso:
 * 
 * 1) Se factoriza la matriz A en 2 matrices L y U, tal que A = L*U, siendo
 *      -> A: una matriz cuadrada de n * n.
 *      -> L: una matriz triangular inferior de dimensión n * n.
 *      -> U: una matriz triangular superior de dimensión n * n.
 * Para realizar la factorización se utiliza el método de triangularización de Gauss.
 *
 * 2) Se invierte la matriz L mediante el método de sustitución directa.
 * 3) Se invierte la matriz U mediante el método de sustitución inversa.
 * 4) Multiplicamos la inversa de U con la inversa de L y esto nos da la inversa de A.
 *
 * Esta es la demestración matemática del proceso
 *      A = L*U
 *      inversa(A) = inversa(L*U)
 *      inversa(A) = inversa(U) * inversa(L)
 */

/* Inclusión de bibliotecas propias */
#include "matrices.h"
#include "inversa.h"
#include "entradasalida.h"

/* Inclusión de bicliotecas estandares */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>


/* Sección de implementación de funciones */

int main(void) {

    // Imprimimos la bienvenida
    printf("============================================================================\n");
    printf("Cálculo la inversa de una matriz. VERSIÓN SECUENCIAL\n");
    printf("============================================================================\n");

    // Obtenemos la matriz que invertiremos y su tamaño.
    struct MATRIZ *matriz = obtenerMatrizDelUsuario();

//    imprimirEnOctave(matriz, "A");

    // En esta variable guardaremos el instante en que el cálculo comienza.
    time_t instanteInicial = time(NULL);
    
    // Calculamos la inversa de la matriz especificada
    printf("Calculamos la inversa de la matriz\n");
    struct MATRIZ *matrizInvertida = inversa(matriz);

    // Ya no necesitamos la matriz original
    eliminarMatriz(matriz);

    // Si la matriz devuelta fue NULL, salir
    if (matrizInvertida==NULL) {
        printf("\nNo se pudo calcular la inversa de la matriz especificada.\n\n");
        return EXIT_FAILURE;
    }

    // Guardamos el momento final
    time_t instanteFinal = time(NULL);

    // Calculamos e imprimimos el tiempo que tardó en ejecutarse el programa
    int tiempoEjecucion = difftime(instanteFinal,instanteInicial);
    printf("\nTiempo de ejecucion: %d segundos\n",tiempoEjecucion);

    //imprimirEnOctave(matrizInvertida, "B");

    // Guardamos la inversa calculada.
    almacenarMatriz(matrizInvertida, "matriz invertida");

    // Imprimimos la despedida
    printf("\n\n====================================================================\n");
    printf("Fin del programa\n");
    printf("====================================================================\n\n");

    return (EXIT_SUCCESS);
    
}
